package net.wanglu.www.zzz.rule.sva;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.trees.Tree;

public class MeasuresAsSubj extends _SvaRule {
	
	public static final Pattern Times = Pattern.compile("\\b\\w+/CD seconds/NNS\\b|\\b\\w+/CD minutes/NNS\\b|\\b\\w+/CD hours/NNS\\b|\\b\\w+/CD days/NNS\\b|\\b\\w+/CD weeks/NNS\\b|\\b\\w+/CD months/NNS\\b|\\b\\w+/CD years/NNS\\b|\\b\\w+/CD decades/NNS\\b|\\b\\w+/CD centuries/NNS\\b");
	public static final Pattern Length = Pattern.compile("\\b\\w+/CD inches/NNS\\b|\\b\\w+/CD millimeters/NNS\\b|\\b\\w+/CD centimeters/NNS\\b|\\b\\w+/CD feet/NNS\\b|\\b\\w+/CD centimeters/NNS\\b|\\b\\w+ yards/NNS\\b|\\b\\w+/CD meters/NNS\\b|\\b\\w+/CD miles/NNS\\b|\\b\\w+/CD kilometers/NNS\\b");
	public static final Pattern Capacity = Pattern.compile("\\b\\w+/CD teaspoons/NNS\\b|\\b\\w+/CD milliliters/NNS\\b|\\b\\w+/CD tablespoons/NNS\\b|\\b\\w+/CD milliliters/NNS\\b|\\b\\w+/CD fluid/JJ ounces/NNS\\b|\\b\\w+/CD milliliters/NNS\\b|\\b\\w+/CD cups/NNS\\b|\\b\\w+/CD liters/NNS\\b|\\b\\w+/CD pints/NNS\\b|\\b\\w+/CD liters/NNS\\b|\\b\\w+/CD quarts/NNS\\b|\\b\\w+/CD liters/NNS\\b|\\b\\w+/CD gallons/NNS\\b|\\b\\w+/CD liters/NNS\\b");
	public static final Pattern Weight = Pattern.compile("\\b\\w+/CD ounces/NNS\\b|\\b\\w+/CD grams/NNS\\b|\\b\\w+/CD pounds/NNS\\b|\\b\\w+/CD kilograms/NNS\\b|\\b\\w+/CD short/JJ tons/NNS\\b|\\b\\w+/CD etric/JJ tons/NNS\\b");
	public static final Pattern Area = Pattern.compile("\\b\\w+/CD square/JJ inches/NNS\\b|\\b\\w+/CD square/JJ centimeters/NNS\\b|\\b\\w+/CD square/JJ feet/NNS\\b|\\b\\w+/CD square/JJ meters/NNS\\b|\\b\\w+/CD square/JJ yards/NNS\\b|\\b\\w+/CD square/JJ meters/NNS\\b|\\b\\w+/CD square/JJ miles/NNS\\b|\\b\\w+/CD square/JJ kilometers/NNS\\b|\\b\\w+/CD acres/NNS\\b|\\b\\w+/CD hectares/NNS\\b");
	public static final Pattern Money = Pattern.compile("\\b\\w+/CD pounds/NNS\\b|\\b\\w+/CD pennies/NNS\\b|\\b\\w+/CD dollars/NNS\\b|\\b\\w+/CD quarters/NNS\\b|\\b\\w+/CD cents/NNS\\b|\\b\\w+/CD yuans/NNS\\b");

	public static final Pattern DeterminerMeasures = Pattern.compile("");
	public final int MeasuresFlag =1;
	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		Tree subjAncestor = nst.getSubjectAncestor();
		
		ArrayList<TaggedWord> tags = subjAncestor.taggedYield();
		sb.clear();
		for (int j = 0; j < tags.size(); j++) {
			sb.append(tags.get(j).toString()).append(" ");
		}
		
		if ( Times.matcher(sb.toString()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setFlag(this.MeasuresFlag);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Length.matcher(sb.toString()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setFlag(this.MeasuresFlag);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Capacity.matcher(sb.toString()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setFlag(this.MeasuresFlag);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Weight.matcher(sb.toString()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setFlag(this.MeasuresFlag);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Area.matcher(sb.toString()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setFlag(this.MeasuresFlag);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Money.matcher(sb.toString()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setFlag(this.MeasuresFlag);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		}
		
		return Rule.Inapplicable;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		BadEgg egg = (BadEgg) objects[0];
		sb.clear();
		if ( egg.getFlag() == this.MeasuresFlag) {
			sb.append("<p>");
			sb.append("表示时间，距离，金钱，重量，度量，容量，温度等的复数名词做主语，通常看作一个整体，根据概念一致的原则，谓语动词用单数形式。例如：");
			sb.append("<br>");
			sb.append("Fifteen years represents a long period of his life.");
			sb.append("<br>");
			sb.append("Ten dollars is all I have left.");
			sb.append("<br>");
			sb.append("但如把这些名词当作个体看待，谓语动词也可以依据语法一致原则，采用复数形式。例如：");
			sb.append("<br>");
			sb.append("The past foure weeks have been the direst in the country's history.");
			sb.append("<br>");
			sb.append("Tweleve inches make one foot.");
			sb.append("</p>");			
		}

		return sb.toString();
	}
}
